home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / Examples / USBModem / ShimSerialHAL.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-25  |  21.3 KB  |  932 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShimSerialHAL.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998-1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18. */
  19.  
  20. #include    <Gestalt.h>
  21. #include    <Errors.h>
  22.  
  23. #include    "Modem.h"
  24. #include    "ModemVersion.h"
  25. #include    "ShimSerialHAL.h"
  26. #include    "ModemDriver.h"
  27.  
  28. /************************************************************************************/
  29. //
  30. //    SerHAL_Entry
  31. //
  32. //    This is the main driver entry point.
  33. //
  34. /************************************************************************************/
  35.  
  36. OSErr SerHAL_Entry(UInt16 HdwSelector, ParmBlkPtr pb, UInt32 RefCon)
  37. {
  38. #pragma unused (RefCon)
  39.     OSErr    err = noErr;
  40.     
  41.     switch (HdwSelector)
  42.         {
  43.             case SerHAL_Initialize:
  44.                 // only do the open stuff once per driver pair
  45.                 if (gGlobals->openSession == false)
  46.                      err = HAL_DoOpenSession();
  47.                 break;
  48.                 
  49.             case SerHAL_Terminate:
  50.                 // only do the close stuff once per driver pair
  51.                 if (gGlobals->openSession)
  52.                     err = HAL_DoCloseSession();
  53.                 break;
  54.                 
  55.             case SerHAL_Read:
  56.                 //    attempt to fill read request immediately
  57.                 //    from any pending data in the input buffer
  58.                 err = HAL_FillReadRequest((IOParam*)pb);
  59.                 HAL_InputFlowControl();
  60.                 //    if it's not completed (pending) save the pb
  61.                 if (err > noErr)
  62.                     gGlobals->pbIn = pb;
  63.                 break;
  64.                 
  65.             case SerHAL_Write:
  66.                 err = USBSerialWrite((IOParam*)pb);
  67.                 if (err > noErr)
  68.                     gGlobals->pbOut = pb;
  69.                 break;
  70.                 
  71.             case SerHAL_SetConfiguration:
  72.                 err = HAL_SetConfiguration(*(UInt16*)pb->cntrlParam.csParam);
  73.                 break;
  74.                 
  75.             case SerHAL_SetInputBuffer:
  76.                 err = HAL_SetInputBuffer(*(Ptr*)pb->cntrlParam.csParam, *(UInt16*)(((Ptr)pb->cntrlParam.csParam) + 4));
  77.                 break;
  78.                 
  79.             case SerHAL_SetFlowControl:
  80.                 HAL_SetFlowControl((SerShk*)pb->cntrlParam.csParam, pb->cntrlParam.csCode);
  81.                 break;
  82.                 
  83.             case SerHAL_SetBreak:
  84.                 USBSendBreak((pb->cntrlParam.csCode == kSERDSetBreak));
  85.                 break;
  86.                 
  87.             case SerHAL_SetDTERate:
  88.                 // check csCode first to see what the real rate is
  89.                 if (pb->cntrlParam.csCode == kSERD115KBaud)
  90.                 {
  91.                     *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(115200);
  92.                 } else {
  93.                     if (pb->cntrlParam.csCode == kSERD230KBaud)
  94.                     {
  95.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(230400);
  96.  
  97.                     } else {
  98.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(*(UInt16*)pb->cntrlParam.csParam);
  99.                     }
  100.                 }            
  101.                 break;
  102.                 
  103.             case SerHAL_SetDTR:
  104.                 USBSetDTRState((pb->cntrlParam.csCode == kSERDAssertDTR));
  105.                 USBSetControlLineState();
  106.                 break;
  107.                 
  108.             case SerHAL_SetParity:
  109.                 HAL_SetParity((pb->cntrlParam.csCode == kSERDSetPEAltChar), *(unsigned char*)pb->cntrlParam.csParam, *(((unsigned char*)pb->cntrlParam.csParam)+1));
  110.                 break;
  111.                 
  112.             case SerHAL_SetXOffFlag:
  113.                 HAL_SetXOffFlag(pb->cntrlParam.csCode == kSERDSetXOffFlag);
  114.                 break;
  115.                 
  116.             case SerHAL_SendXOn:
  117.                 HAL_SendXOn((pb->cntrlParam.csCode == kSERDSendXOn));
  118.                 break;
  119.                 
  120.             case SerHAL_SendXOff:
  121.                 HAL_SendXOff((pb->cntrlParam.csCode == kSERDSendXOff));
  122.                 break;
  123.                 
  124.             case SerHAL_Miscellaneous:
  125.                 // only interested in DTR (for now)
  126.                 if ((UInt8)pb->cntrlParam.csParam[0] & kOptionPreserveDTR) 
  127.                 {
  128.                     USBSetCloseDTR();
  129.                 }
  130.                 break;
  131.                 
  132.             case SerHAL_GetBuffer:
  133.                 *(UInt32*)(&pb->cntrlParam.csParam[0]) = HAL_GetBuffer();
  134.                 break;
  135.                 
  136.             case SerHAL_GetStatus:
  137.                 HAL_GetStatus((SerStaRec*)pb->cntrlParam.csParam);
  138.                 break;
  139.                 
  140.             case SerHAL_GetVersion:
  141.                 *(char *)pb->cntrlParam.csParam = DriverVersion;
  142.                 break;
  143.                 
  144.             case SerHAL_ControlExtend:
  145.                 err = HAL_ControlExtend(pb);
  146.                 break;
  147.                 
  148.             case SerHAL_StatusExtend:
  149.                 err = HAL_StatusExtend(pb);
  150.                 break;
  151.                 
  152.             case SerHAL_KillRead:
  153.                 gGlobals->pbIn = nil;    // Device Manager handles I/O queue
  154.                 break;
  155.                 
  156.             case SerHAL_KillWrite:
  157.                 gGlobals->pbOut = nil;    // Device Manager handles I/O queue
  158.                 break;
  159.                 
  160.             default:
  161.                 err = -1;                // unknown selector (for now)
  162.                 break;
  163.         }
  164.     
  165.     return err;
  166. }
  167.  
  168. /************************************************************************************/
  169. //
  170. //    HAL_SetConfiguration
  171. //
  172. //    Serial driver SerReset control call.
  173. //
  174. /************************************************************************************/
  175.  
  176. OSErr HAL_SetConfiguration(UInt16 config)
  177. {
  178.  
  179.     UInt16        baudRate;
  180.     LineParms    Line_Coding;
  181.  
  182.     TraceMessage(0,kCRMName"- Entering HAL_SetConfiguration");
  183.     
  184.     switch (config & kSerConfigBaudMask)
  185.     {
  186.         case baud300: baudRate = 300; break;
  187.         case baud600: baudRate = 600; break;
  188.         case baud1200: baudRate = 1200; break;
  189.         case baud1800: baudRate = 1800; break;
  190.         case baud2400: baudRate = 2400; break;
  191.         case baud3600: baudRate = 3600; break;
  192.         case baud4800: baudRate = 4800; break;
  193.         case baud7200: baudRate = 7200; break;
  194.         case baud9600: baudRate = 9600; break;
  195.         case baud19200: baudRate = 19200; break;
  196.         case baud38400: baudRate = 38400; break;
  197.         case baud57600: baudRate = 57600; break;
  198.         default: baudRate = 57600; break;
  199.     }
  200.         
  201.     Line_Coding.DTERate1 = USBToHostWord(baudRate);        // All because of Intel format
  202.     Line_Coding.DTERate2 = 0;
  203.     
  204.     switch (config & kSerConfigLenMask)
  205.     {
  206.         case data5: 
  207.             Line_Coding.DataBits = k5DataBits;
  208.             break;
  209.         case data6: 
  210.             Line_Coding.DataBits = k6DataBits;
  211.             break;
  212.         case data7: 
  213.             Line_Coding.DataBits = k7DataBits;
  214.             break;
  215.         case data8: 
  216.             Line_Coding.DataBits = k8DataBits;
  217.             break;
  218.         default: 
  219.             Line_Coding.DataBits = k8DataBits;
  220.             break;
  221.     }
  222.     
  223.     switch (config & kSerConfigParityMask)
  224.     {
  225.         case noParity: 
  226.             Line_Coding.ParityType = kNoParity;
  227.             break;
  228.         case oddParity: 
  229.             Line_Coding.ParityType = kOddParity;
  230.             break;
  231.         case evenParity: 
  232.             Line_Coding.ParityType = kEvenParity;
  233.             break;
  234.         default: 
  235.             Line_Coding.ParityType = kNoParity;
  236.             break;
  237.     }
  238.     
  239.     switch (config & kSerConfigStopMask)
  240.     {
  241.         case stop10: 
  242.             Line_Coding.CharFormat = k1StopBit;
  243.             break;
  244.         case stop15: 
  245.             Line_Coding.CharFormat = k15StopBits;
  246.             break;
  247.         case stop20: 
  248.             Line_Coding.CharFormat = k2StopBits;
  249.             break;
  250.         default: 
  251.             Line_Coding.CharFormat = k1StopBit;
  252.             break;
  253.     }
  254.     
  255.     //    reset the baud rate and other values
  256.  
  257.     USBSetLineCoding(Line_Coding);
  258.  
  259.     return noErr;
  260. }
  261.  
  262. /************************************************************************************/
  263. //
  264. //    HAL_SetInputBuffer
  265. //
  266. //    Select and initialize the serial input buffer.
  267. //
  268. /************************************************************************************/
  269.  
  270. OSErr HAL_SetInputBuffer(Ptr newBuf, UInt16 bufLen)
  271. {
  272.     OSErr    err;
  273.     long    result;
  274.     Boolean    vmPresent;
  275.         
  276.     TraceMessage(0,kCRMName"- Entering HAL_SetInputBuffer");
  277.     
  278.     //  check for presence of virtual memory
  279.     
  280.     err = Gestalt(gestaltVMAttr,&result);
  281.     vmPresent = ((err == noErr) && (result >= gestaltVMPresent));
  282.     
  283.     //  un-hold any previous input buffer
  284.     
  285.     if (vmPresent && gGlobals->inBufPtr && (gGlobals->inBufPtr != gGlobals->builtInBuffer))
  286.         UnholdMemory(gGlobals->inBufPtr, gGlobals->inBufLen);
  287.     
  288.     //    assign our local buffer as the default
  289.     
  290.     gGlobals->inBufPtr = gGlobals->builtInBuffer;
  291.     gGlobals->inBufLen = kBuiltInBufferSize;
  292.     
  293.     //    reset buffer indexes
  294.     
  295.     gGlobals->inBufStartIndex = 0;
  296.     gGlobals->inBufEndIndex = 0;
  297.         
  298.     //    a non-zero buffer length means use client buffer
  299.     //    a zero buffer length means use the default buffer
  300.     
  301.     if (bufLen && newBuf)
  302.     {
  303.         //  we need to make sure the buffer stays in physical memory
  304.         
  305.         if (vmPresent)
  306.         {
  307.             err = HoldMemory(newBuf, bufLen);
  308.             if (err != noErr)
  309.                 return err;
  310.         }
  311.         
  312.         //    assign client buffer
  313.         gGlobals->inBufPtr = (UInt8 *) newBuf;
  314.         gGlobals->inBufLen = bufLen;
  315.     }
  316.     
  317.     return noErr;
  318. }
  319.  
  320. /************************************************************************************/
  321. //
  322. //    HAL_SetFlowControl
  323. //
  324. //    Process the csSerHShake & csSerHShakeDTR control calls.
  325. //
  326. /************************************************************************************/
  327.  
  328. void HAL_SetFlowControl(SerShk *shkNew, UInt16 csCode)
  329. {
  330.     
  331.     TraceMessage(0,kCRMName"- Entering HAL_SetFlowControl");
  332.     
  333.     //
  334.     //    set new cts value
  335.     //
  336.  
  337.     gGlobals->serShk.fCTS = shkNew->fCTS;
  338.  
  339.     //
  340.     //    copy over new xon / xoff characters
  341.     //
  342.  
  343.     gGlobals->serShk.xOn = shkNew->xOn;
  344.     gGlobals->serShk.xOff = shkNew->xOff;
  345.  
  346.     //
  347.     //    handle any change in software output flow control
  348.     //    this is ignored for now
  349.  
  350.     gGlobals->serShk.fXOn = 0;
  351.  
  352.     //    copy over the errs & evts options fields
  353.     //    notice we do _nada_ with the events (no _PostEvent, etc.)
  354.     
  355.     gGlobals->serShk.errs = shkNew->errs & (parityErr | hwOverrunErr | framingErr);
  356.     gGlobals->serShk.evts = shkNew->evts;
  357.  
  358.     //    handle any change in software input flow control
  359.     //    again this is ignored for now
  360.  
  361.     gGlobals->serShk.fInX = 0;
  362.  
  363.     //    if csCode is newer kSERDHandshake,
  364.     //    take account of the fDTR field
  365.  
  366.     if (csCode == kSERDHandshake)
  367.     {
  368.         
  369.         //
  370.         //    handle any change in hardware input flow control
  371.         //    ignored for now
  372.         //
  373.  
  374.         gGlobals->serShk.fDTR = 1;
  375.  
  376.     }
  377. }
  378.  
  379. /************************************************************************************/
  380. //
  381. //    HAL_SendXOn
  382. //
  383. //    Determines whether to send XOn character.
  384. //    This is a stub for now
  385. //
  386. /************************************************************************************/
  387.  
  388. void HAL_SendXOn(Boolean always)
  389. {
  390. #pragma unused (always)
  391.  
  392.     TraceMessage(0,kCRMName"- Entering HAL_SendXOn");
  393.     
  394. }
  395.  
  396. /************************************************************************************/
  397. //
  398. //    HAL_SendXOff
  399. //
  400. //    Determines whether to send XOff character.
  401. //    This is a stub for now
  402. //
  403. /************************************************************************************/
  404.  
  405. void HAL_SendXOff(Boolean always)
  406. {
  407. #pragma unused (always)
  408.  
  409.     TraceMessage(0,kCRMName"- Entering HAL_SendXOff");
  410.  
  411. }
  412.  
  413. /************************************************************************************/
  414. //
  415. //    HAL_SendXOffFlag
  416. //
  417. //    Determines whether to send XOff character.
  418. //
  419. /************************************************************************************/
  420.  
  421. void HAL_SetXOffFlag(Boolean state)
  422. {
  423. #pragma unused (state)
  424.  
  425.     TraceMessage(0,kCRMName"- Entering HAL_SetXOffFlag");
  426.     
  427.     gGlobals->serStat.xOffHold = 0;            // always off for now
  428.     
  429. }
  430.  
  431. /************************************************************************************/
  432. //
  433. //    HAL_GetStatus
  434. //
  435. //    Status routine fills in the SerStaRec record.
  436. //
  437. /************************************************************************************/
  438.  
  439. void HAL_GetStatus(SerStaRec *statRec)
  440. {
  441.     
  442.     TraceMessage(0,kCRMName"- Entering HAL_GetStatus");
  443.     
  444.     //    get & reset cumErrs
  445.     
  446.     statRec->cumErrs = gGlobals->serStat.cumErrs;
  447.     gGlobals->serStat.cumErrs = 0;
  448.  
  449.     //    has an xOff been sent to stop input?
  450.  
  451.     statRec->xOffSent = gGlobals->serStat.xOffSent;  
  452.  
  453.     //    is there a pending read request? 
  454.  
  455.     statRec->rdPend = (gGlobals->pbIn != nil);
  456.  
  457.     //    is there a pending write request?
  458.  
  459.     statRec->wrPend = (gGlobals->pbOut != nil);
  460.  
  461.     //    cts & xOff output flow control hold flags
  462.  
  463.     statRec->ctsHold = false;                    // always false for now?
  464.     statRec->xOffHold = gGlobals->serStat.xOffHold; 
  465.     
  466. }
  467.  
  468. /************************************************************************************/
  469. //
  470. //    HAL_GetBuffer
  471. //
  472. //    status routine computes & returns the number of bytes pending in the receive buffer 
  473. //
  474. /************************************************************************************/
  475.  
  476. UInt32 HAL_GetBuffer(void)
  477. {
  478.     SInt32        count;
  479.     OSStatus    err;
  480.     
  481. //    TraceMessage(0,kCRMName"- Entering HAL_GetBuffer");
  482.     
  483.     err = CurrentExecutionLevel();                // Only at task time
  484.     if (err)
  485.     {
  486.         count = 0;
  487.     } else {
  488.         count = ((SInt32)gGlobals->inBufEndIndex - (SInt32)gGlobals->inBufStartIndex);
  489.     
  490.         if ( count < 0 ) 
  491.             count += gGlobals->inBufLen;
  492.     }
  493.     
  494.     return count;
  495. }
  496.  
  497. /************************************************************************************/
  498. //
  499. //    HAL_SetDTERate
  500. //
  501. /************************************************************************************/
  502.  
  503. UInt16 HAL_SetDTERate(UInt32 baudRate)
  504. {
  505.  
  506.     TraceMessage(0,kCRMName"- Entering HAL_SetDTERate");
  507.     
  508.     //    validate the requested baud rate
  509.     
  510.     if (baudRate)
  511.     {
  512.         if (baudRate > kMaxBaudRate)
  513.             baudRate = kMaxBaudRate;
  514.             
  515.         gGlobals->baudRate = baudRate;
  516.     } else {
  517.         baudRate = gGlobals->baudRate;
  518.     }
  519.     
  520.     USBSetBaudRate(baudRate);
  521.     
  522.     //    return actual baud rate used (this is historical)
  523.  
  524.     return baudRate;
  525. }
  526.  
  527. /************************************************************************************/
  528. //
  529. //    HAL_SetParity
  530. //
  531. //    Assigns parity error replacement character and alternate replacment character.
  532. //    if peChar is zero then no parity error character substitution.
  533. //    This is a stub for now
  534. //
  535. /************************************************************************************/
  536.  
  537. void HAL_SetParity(Boolean alt, char peChar, char peAltChar)
  538. {
  539. #pragma unused (alt, peChar, peAltChar)
  540.  
  541.     TraceMessage(0,kCRMName"- Entering HAL_SetParity");
  542.  
  543. }
  544.  
  545. /************************************************************************************/
  546. //
  547. //    HAL_FillReadRequest
  548. //
  549. //    Attempts to copy requested bytes from the internal serial buffer into request 
  550. //    parameter block.
  551. //
  552. /************************************************************************************/
  553.  
  554. OSErr HAL_FillReadRequest(IOParam *pb)
  555. {
  556.     OSErr    result;
  557.     UInt16    endIndex;
  558.     UInt16    startIndex;
  559.  
  560.     TraceMessage(0,kCRMName"- Entering HAL_FillReadRequest");
  561.  
  562.     result = 1;
  563.     while (result > noErr)
  564.     {
  565.  
  566.         //    this can be interrupted to add data to the internal buffer
  567.         //    so we update inBufStartIndex and inBufEndIndex each time
  568.         //    if there is nothing in the input buffer, leave quietly
  569.  
  570.         endIndex = gGlobals->inBufEndIndex;
  571.         startIndex = gGlobals->inBufStartIndex;
  572.         
  573.         if (startIndex == endIndex) 
  574.             break;
  575.  
  576.         //    copy byte into read request buffer and bump actual count
  577.  
  578.         pb->ioBuffer[pb->ioActCount] = gGlobals->inBufPtr[startIndex];
  579.         pb->ioActCount++;
  580.  
  581.         //    now update internal buffer inBufStartIndex
  582.  
  583.         startIndex++;
  584.         
  585.         if (startIndex >= gGlobals->inBufLen) 
  586.             startIndex = 0;
  587.             
  588.         gGlobals->inBufStartIndex = startIndex;
  589.  
  590.         //    lastly, check if we've satisfied the request
  591.  
  592.         if (pb->ioReqCount <= pb->ioActCount)
  593.             result = noErr;
  594.     }
  595.  
  596.     return result;
  597. }
  598.  
  599. /************************************************************************************/
  600. //
  601. //    HAL_EnableSerialDevice
  602. //
  603. //    Called once at driver open time to configure the hardware and get things going etc.
  604. //
  605. /************************************************************************************/
  606.  
  607. void HAL_EnableSerialDevice(void)
  608. {    
  609.     
  610.     TraceMessage(0,kCRMName"- Entering HAL_EnableSerialDevice");
  611.     
  612.     USBSetRTSState(1);
  613.     USBSetDTRState(1);
  614.     
  615.     USBSetControlLineState();
  616.     
  617.     HAL_SetDTERate(0);
  618.  
  619.     // Start the read mechanism
  620.     
  621.     USBStartReadPolling();
  622.     
  623. }
  624.  
  625. /************************************************************************************/
  626. //
  627. //    HAL_DisableSerialDevice
  628. //
  629. //    Called once when the driver is closed to shut things down
  630. //
  631. /************************************************************************************/
  632.  
  633. void HAL_DisableSerialDevice(void)
  634. {
  635.     
  636.     TraceMessage(0,kCRMName"- Entering HAL_DisableSerialDevice");
  637.  
  638.     USBStopReadPolling();
  639.  
  640.     USBSetRTSState(0);
  641.     USBSetDTRState(0);
  642.     
  643.     USBSetControlLineState();
  644.     
  645. }
  646.  
  647. /************************************************************************************/
  648. //
  649. //    HAL_InputFlowControl
  650. //
  651. //    Handles hardware (dtr or rts) and software (xon / xoff) input flow control
  652. //    This is a stub for now
  653. //
  654. /************************************************************************************/
  655.  
  656. void HAL_InputFlowControl(void)
  657. {
  658.  
  659.     TraceMessage(0,kCRMName"- Entering HAL_InputFlowControl");
  660.  
  661. }
  662.  
  663. /************************************************************************************/
  664. //
  665. //    HAL_EnableInput
  666. //
  667. //    Sets the DTR state
  668. //    This is a stub for now
  669. //
  670. /************************************************************************************/
  671.  
  672. void HAL_EnableInput(Boolean enable)
  673. {
  674. #pragma unused (enable)
  675.  
  676.     TraceMessage(0,kCRMName"- Entering HAL_EnableInput");
  677.  
  678. }
  679.  
  680. /************************************************************************************/
  681. //
  682. //    HAL_EnableOutput
  683. //
  684. //    Handles output flow control
  685. //    This is a stub for now
  686. //
  687. /************************************************************************************/
  688.  
  689. void HAL_EnableOutput(void)
  690. {
  691.  
  692.     TraceMessage(0,kCRMName"- Entering HAL_EnableOutput");
  693.     
  694. }
  695.  
  696. /************************************************************************************/
  697. //
  698. //    HAL_DoOpenSession
  699. //
  700. //    Process an OpenDriver request to the stub drivers
  701. //
  702. /************************************************************************************/
  703.  
  704. OSErr HAL_DoOpenSession(void)
  705. {
  706.  
  707.     OSErr        err;
  708.     LineParms    Line_Coding;
  709.     
  710.     TraceMessage(0,kCRMName"- Entering HAL_DoOpenSession");
  711.     
  712.     // only allow one open session
  713.     
  714.     if (gGlobals->openSession)
  715.         return openErr;
  716.         
  717.     //    reset internal indexes, buffers, etc.
  718.     
  719.     err = HAL_SetInputBuffer(nil, 0);
  720.     if (err)
  721.         return openErr;
  722.     
  723.     //  since we've cleared the buffer to zero initially we have to explicitly
  724.     //  initialize the baudRate
  725.     
  726.     gGlobals->baudRate = kMaxBaudRate;
  727.     
  728.     //    reset default values for other variables
  729.  
  730.     gGlobals->xOnOffChar = 0;
  731.     gGlobals->peChar = 0;
  732.     gGlobals->peAltChar = 0;
  733.  
  734.     //    reset handshake default values as per scc serial driver
  735.  
  736.     gGlobals->serShk.fXOn = 0;
  737.     gGlobals->serShk.fCTS = 1;
  738.     gGlobals->serShk.xOn = 0;
  739.     gGlobals->serShk.xOff = 0;
  740.     gGlobals->serShk.evts = 0;
  741.     gGlobals->serShk.fInX = 0;
  742.     gGlobals->serShk.fDTR = 1;
  743.  
  744.     //    reset serial status record
  745.  
  746.     gGlobals->serStat.cumErrs = 0;
  747.     gGlobals->serStat.xOffSent = 0;
  748.     gGlobals->serStat.rdPend = 0;
  749.     gGlobals->serStat.wrPend = 0;
  750.     gGlobals->serStat.ctsHold = 0;
  751.     gGlobals->serStat.xOffHold = 0;
  752.     
  753.     // Line coding structure
  754.     
  755.     Line_Coding.DTERate1 = 0;            // gets handled later with
  756.     Line_Coding.DTERate2 = 0;            // value from gGlobals->baudRate
  757.     Line_Coding.CharFormat = k1StopBit;
  758.     Line_Coding.ParityType = kNoParity;
  759.     Line_Coding.DataBits = k8DataBits;
  760.     
  761.     InitLineCoding(Line_Coding);
  762.     
  763.     //    Let's get started
  764.     
  765.     HAL_EnableSerialDevice();
  766.     
  767.     // we now have an open session
  768.     
  769.     gGlobals->openSession = true;
  770.         
  771.     return noErr;
  772. }
  773.  
  774. /************************************************************************************/
  775. //
  776. //    HAL_DoCloseSession
  777. //
  778. //    Process a CloseDriver request to the stub drivers
  779. //
  780. /************************************************************************************/
  781.  
  782. OSErr HAL_DoCloseSession(void)
  783. {
  784.  
  785.     TraceMessage(0,kCRMName"- Entering HAL_DoCloseSession");
  786.  
  787.     HAL_DisableSerialDevice();
  788.             
  789.     //    reset internal indexes, buffers, etc. - this
  790.     //    is important for vm to unhold memory on any
  791.     //    buffer the client may have requested earlier
  792.     
  793.     HAL_SetInputBuffer(nil, 0);
  794.                     
  795.     // we no longer have an open session
  796.         
  797.     gGlobals->openSession = false;
  798.  
  799.     return noErr;
  800. }
  801.  
  802. /************************************************************************************/
  803. //
  804. //    HAL_ControlExtend
  805. //
  806. //    User extensions to control
  807. //
  808. /************************************************************************************/
  809.  
  810. OSErr HAL_ControlExtend(ParmBlkPtr pb)
  811. {
  812.  
  813.     TraceMessage(0,kCRMName"- Entering HAL_ControlExtend");
  814.  
  815.     if (pb->cntrlParam.csCode == kpciGetDCD)
  816.     {
  817.         ((char *)(pb->cntrlParam.csParam))[6] = USBGetDCDValue();
  818.         return noErr;
  819.     }
  820.     
  821.     return controlErr;
  822. }
  823.  
  824. /************************************************************************************/
  825. //
  826. //    HAL_StatusExtend
  827. //
  828. //    User extensions to status
  829. //
  830. /************************************************************************************/
  831.  
  832. OSErr HAL_StatusExtend(ParmBlkPtr pb)
  833. {
  834. #pragma unused (pb)
  835.  
  836.     TraceMessage(0,kCRMName"- Entering HAL_StatusExtend");
  837.     
  838.     return statusErr;
  839. }
  840.  
  841. /************************************************************************************/
  842. //
  843. //    HAL_ShimInput
  844. //
  845. //    Handles the coordination of input and the requestors buffer.
  846. //
  847. /************************************************************************************/
  848.  
  849. void HAL_ShimInput(UInt8 *buf, UInt32 count)
  850. {
  851.     IOParam                 *pb;
  852.     OSErr                    result;
  853.     register UInt16            nextIndex;
  854.     register unsigned char    rcvByte;
  855.     unsigned char            cumErrs;
  856.     
  857.     TraceMessage(0,kCRMName"- Entering ShimInput");
  858.         
  859.     //    set return result to incomplete
  860.  
  861.     result = 1;
  862.     cumErrs = 0;
  863.  
  864.     while (count--)
  865.     {
  866.  
  867.         //  handle reading of data available in the hardware receive buffer
  868.         
  869.         rcvByte = *buf++;
  870.                             
  871.         //    compute index into our input buffer
  872.  
  873.         nextIndex = gGlobals->inBufEndIndex + 1;
  874.         if ( nextIndex >= gGlobals->inBufLen ) 
  875.             nextIndex = 0;
  876.             
  877.         //    stuff the character into the input buffer and update the index
  878.  
  879.         gGlobals->inBufPtr[gGlobals->inBufEndIndex] = rcvByte;
  880.         gGlobals->inBufEndIndex = nextIndex;
  881.  
  882.         //    check for input buffer overflow
  883.  
  884.         if (gGlobals->inBufEndIndex == gGlobals->inBufStartIndex)
  885.         {
  886.             //    mark that we've had an overrun
  887.  
  888.             gGlobals->serStat.cumErrs |= swOverrunErr;
  889.             cumErrs |= swOverrunErr;
  890.                 
  891.             //    drop oldest character from our internal buffer
  892.  
  893.             gGlobals->inBufStartIndex++;
  894.             if (gGlobals->inBufStartIndex >= gGlobals->inBufLen)
  895.                 gGlobals->inBufStartIndex = 0;
  896.                 
  897.             //    we've had a software overrun -- we quit now and let the
  898.             //    client get a chance to read in the existing bytes -- 
  899.         }
  900.         
  901.         //    check for an outstanding read request
  902.         
  903.         pb = (IOParam *)gGlobals->pbIn;
  904.         if (pb)
  905.         {
  906.             //    copy bytes from input buffer into pb read buffer
  907.             //    (result is either 1=incomplete or 0=complete)
  908.     
  909.             result = HAL_FillReadRequest(pb);
  910.             
  911.             //    handle errors that cause read aborts
  912.             
  913.             if (cumErrs & gGlobals->serShk.errs) 
  914.                 result = rcvrErr;
  915.             
  916.             //    if we have fulfilled this read request, we
  917.             //  need to call IOCommandIsComplete on it
  918.             //  and continue processing with the next request
  919.             
  920.             if ( result <= noErr )
  921.             {
  922.                 gGlobals->pbIn = nil;
  923.                 ShimIOComplete((union ParamBlockRec *)pb, result);
  924. //                break;
  925.             }
  926.         }
  927.     }
  928.     
  929.     // clean up after ourselves
  930. //    if (result <= noErr)
  931. //        ShimIOComplete((union ParamBlockRec *)pb, result);
  932. }